package com.yx.udp;

import androidx.annotation.LongDef;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.widget.VideoView;

import androidx.appcompat.app.AppCompatActivity;

import com.yx.udp.util.Crc16Utils;
import com.yx.udp.util.UdpPacketParser;

import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.interfaces.IVLCVout;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.EventListener;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android_serialport_api.SerialPort;

public class MainActivity extends AppCompatActivity implements
        MediaPlayer.OnPreparedListener,
        MediaPlayer.OnErrorListener,
        MediaPlayer.OnInfoListener {
    private String TAG = "MainActivity";
    //rtsp
    private LibVLC mLibVLC;
    private org.videolan.libvlc.MediaPlayer mMediaPlayer;
    private org.videolan.libvlc.MediaPlayer mMediaPlayer1;
    IVLCVout vout;
    IVLCVout vout1;
    private VideoView mVideoSurface;
    private VideoView mVideoSurface1;
    private String mCurrentRtspUrl;
    private String uri = "rtsp://192.168.1.169/user=admin_password=tlJwpbo6_channel=1_stream=0&amp;onvif=0.sdp?real_st";
    private String uri1 = "rtsp://192.168.1.168/user=admin_password=tlJwpbo6_channel=1_stream=0&amp;onvif=0.sdp?real_st";
LinearLayout rtsp_ipc;
int succeed_Start_stop_flow=0;
int failure_Start_stop_flow=0;
    boolean Prepare=false;
    boolean Prepare1=false;
    boolean Error=false;
    private void initVLC() {
        Prepare=false;
        Prepare1=false;
        Error=false;
        mVideoSurface.setVideoURI(Uri.parse(uri));
        mVideoSurface1.setVideoURI(Uri.parse(uri1));
        // 设置准备完成监听器
        mVideoSurface.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                Prepare=true;
                Log.d(TAG, "onPrepared2: ");
                if (Prepare&&Prepare1){
                    Log.d(TAG, "onPrepared: ");
                    succeed_Start_stop_flow++;
                }

                // 这里可以添加播放开始前的逻辑
            }
        });
        mVideoSurface1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                Prepare1=true;
                Log.d(TAG, "onPrepared3: ");
                if (Prepare&&Prepare1){
                    Log.d(TAG, "onPrepared1: ");
                    succeed_Start_stop_flow++;
                }

                // 这里可以添加播放开始前的逻辑
            }
        });
        mVideoSurface.setOnErrorListener((mp, what, extra) -> {
            if (!Error){
                failure_Start_stop_flow++;
                Error=true;
            }
            Log.e("RTSP_TEST", "Stream 1 error: " + what + ", " + extra);
            return true;
        });

        mVideoSurface1.setOnErrorListener((mp, what, extra) -> {
            if (!Error){
                failure_Start_stop_flow++;
                Error=true;
            }
            Log.e("RTSP_TEST", "Stream 2 error: " + what + ", " + extra);
            return true;
        });



    }
    //串口485
    static public String ByteArrToHex(byte[] inBytArr,int offset,int byteCount)//??????hex???,????
    {
        StringBuilder strBuilder=new StringBuilder();
        int j=byteCount;
        for (int i = offset; i < j; i++)
        {
            strBuilder.append(Byte2Hex(inBytArr[i]));
        }
        return strBuilder.toString();
    }
    static public String Byte2Hex(Byte inByte)//1???2?Hex??
    {
        return String.format("%02x", inByte).toUpperCase();
    }
    static public String ByteArrToHex(byte[] inBytArr)//??????hex???
    {
        StringBuilder strBuilder=new StringBuilder();
        int j=inBytArr.length;
        for (int i = 0; i < j; i++)
        {
            strBuilder.append(Byte2Hex(inBytArr[i]));
            strBuilder.append(" ");
        }
        return strBuilder.toString();
    }
    private byte[] mValueToSend = {(byte)0x55,(byte)0x04,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00};
    // 使用 UTF-8 编码（最常用）
    String text = "YXFT";
    byte[] utf8Bytes = text.getBytes(StandardCharsets.UTF_8);
    public SerialPort serialPort;
    public OutputStream mOutputStream;
    public InputStream mInputStream;
    public ReadThread mReadThread;
    public SendThread mSendThread;
    private class ReadThread extends Thread{
        public void run()
        {
            super.run();
            int size;
            try
            {
                do
                {
                    byte[] buffer = new byte[64];

                    Thread.sleep(200);
                    Log.d("TAG", "mInputStream: "+mInputStream);


                    size = mInputStream.read(buffer);

                    Log.d("TAG", "buffer: "+size);
                    if (size > 0) {
                        if (size==5){
                            Log.d("TAG", "size > 0 "+ByteArrToHex(buffer,0,5));
                            if (ByteArrToHex(buffer,0,5).equals("EB90C2AAE7")){
                                mSendThread = new SendThread();
                                mSendThread.start();
                            }
                        } else if (size==2) {
                            byte[] buffer1 = new byte[size];
                            for (int i = 0; i < size; i++) {
                                buffer1[i]=buffer[i];
                            }
                            String text = new String(buffer1, StandardCharsets.UTF_8);
                            Log.d(TAG, "size > 0: "+text);

                            if (text.indexOf("OK")!=-1){
                                switch_lock_result.setText("485 测试成功");

                        if (mReadThread != null)
                            mReadThread.interrupt();
                        if (mSendThread != null)
                            mSendThread.interrupt();
                        if (serialPort != null) {
                            serialPort.close();
                            serialPort = null;
                        }
                                Log.d(TAG, "485 测试成功");
                            }
                        }


                    }


                } while (true);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    private class SendThread extends Thread
    {
        public void run()
        {
            super.run();
            try
            {
                do
                {
                    int i=0;
                    Log.d(TAG, "serial测试次数 "+i);
                    if (i>2){




//                        if (mReadThread != null)
//                            mReadThread.interrupt();
//                        if (mSendThread != null)
//                            mSendThread.interrupt();
//                        if (serialPort != null) {
//                            serialPort.close();
//                            serialPort = null;
//                        }

//                        mHandler.sendEmptyMessage(1);


                        return;
                    }
                    Log.d("TAG", "发: ");
                    Thread.sleep(1000);
                    Log.d("TAG", "run2: "+mOutputStream);
                    if (mOutputStream == null){

                        return;

                    }
                    CharSequence t = String.valueOf(500);
                    char[] text = new char[t.length()];

                    Log.d("TAG", "write: "+new String(text).getBytes());
                    mOutputStream.write(utf8Bytes);
                } while (true);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    String ttys5="/dev/ttyS5";
    public void openSerial2(String s){

        try {
            serialPort = new SerialPort(s, 115200, 0);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        mInputStream = serialPort.getInputStream();
        Log.d("TAG", "mInputStream: "+mInputStream);
        Log.d("TAG", "serialPort: "+serialPort);

        mOutputStream = serialPort.getOutputStream();
        Log.d("TAG", "mOutputStream: "+mOutputStream);

        mReadThread = new ReadThread();
        mReadThread.start();
//        mSendThread = new SendThread();
//        mSendThread.start();
    }

    // 协议常量
    private static final short HEADER = (short) 0x55AA;
    private static final byte HANDSHAKE_REQUEST = 0x01;
    private static final byte HANDSHAKE_RESPONSE = 0x02;
    private static final int HANDSHAKE_PORT = 6000; // 控制端握手端口
    private static final int DATA_PORT = 7100;      // 控制端数据端口

    // 设备信息
    private static final String DEVICE_ID = "CTRL-2023-001";
    private static final byte PROTOCOL_VERSION = 0x01;
    private static final short SOFTWARE_VERSION = 0x0102;
    private static final String SERIAL_NUMBER = "SN-87654321";

    // UI组件
    private EditText ipAddressEditText,tem;
    private Button startButton,device_sn,pull_rtsp,set_sn,stopButton, sendButton,deletelog,send,receive,sendheart,sedreset,sendopen,settem,getRealTem,clean_times,battery_off,TimeSyn,getdoor_doorStatus,Door_status;
    private TextView doorstatusTextView,lockstatusTextView, logTextView,test_result,switch_lock_result,Start_stop_flow_result;
    private ScrollView logScrollView;
    private ToggleButton reboottest,set_led,set_vout,set_compressor,switch_lock,ipc,Start_stop_flow,weight,set_camera,Mac;

    // 网络相关
    private DatagramSocket handshakeSocket;
    private DatagramSocket dataSocket;
    private InetAddress appAddress;
    private int appDataPort = 6000; // 上位机数据端口，默认为6000

    // 线程管理
    private ExecutorService executorService;
    private volatile boolean isRunning = false;

    private final Handler handler = new Handler(Looper.getMainLooper());
    private final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        openSerial2(ttys5);
        //心跳包
        mHandler.sendEmptyMessageDelayed(2, 2000);


        mVideoSurface = findViewById(R.id.textureView);
        Mac = findViewById(R.id.Mac);
        device_sn = findViewById(R.id.device_sn);
        set_sn = findViewById(R.id.set_sn);
        set_camera = findViewById(R.id.set_camera);
        pull_rtsp = findViewById(R.id.pull_rtsp);
        Door_status = findViewById(R.id.Door_status);
        Start_stop_flow_result = findViewById(R.id.Start_stop_flow_result);
        mVideoSurface1 = findViewById(R.id.textureView1);
        rtsp_ipc = findViewById(R.id.rtsp_ipc);
        sp=getSharedPreferences("reboottest", Context.MODE_PRIVATE);
        editor = sp.edit();
        // 初始化UI组件
        ipAddressEditText = findViewById(R.id.ipAddressEditText);
        tem = findViewById(R.id.tem);
        startButton = findViewById(R.id.startButton);
        stopButton = findViewById(R.id.stopButton);
        sendButton = findViewById(R.id.sendButton);
        doorstatusTextView = findViewById(R.id.doorstatusTextView);
        lockstatusTextView = findViewById(R.id.lockstatusTextView);
        logTextView = findViewById(R.id.logTextView);
        test_result = findViewById(R.id.test_result);
        weight = findViewById(R.id.weight);
        switch_lock_result = findViewById(R.id.switch_lock_result);
        logScrollView = findViewById(R.id.logScrollView);
        deletelog = findViewById(R.id.deletelog);
        Start_stop_flow = findViewById(R.id.Start_stop_flow);
        send = findViewById(R.id.send);
        sendheart = findViewById(R.id.sendheart);
        receive = findViewById(R.id.receive);
        sedreset = findViewById(R.id.sendreset);
        sendopen = findViewById(R.id.sendopen);
        ipc = findViewById(R.id.ipc);
        reboottest = findViewById(R.id.test);
        settem = findViewById(R.id.settem);
        getRealTem = findViewById(R.id.getRealTem);
        clean_times = findViewById(R.id.clean_times);
        battery_off = findViewById(R.id.battery_off);
        TimeSyn = findViewById(R.id.TimeSyn);
        getdoor_doorStatus = findViewById(R.id.getdoor_doorStatus);
        set_led = findViewById(R.id.set_led);
        set_vout = findViewById(R.id.set_vout);
        set_compressor = findViewById(R.id.set_compressor);
        switch_lock = findViewById(R.id.switch_lock);

        // 设置默认IP
        ipAddressEditText.setText("192.168.1.1");

        // 按钮事件监听
        startButton.setOnClickListener(v -> startCommunication());
        stopButton.setOnClickListener(v -> stopCommunication());
        sendButton.setOnClickListener(v -> sendDataMessage());
        deletelog.setOnClickListener(v -> setDeletelog());
        pull_rtsp.setOnClickListener(v -> Record());

//        set_camera.setOnClickListener(v -> setcameraDirection(0,"设置左柜"));
        set_sn.setOnClickListener(v -> setSn());


        Door_status.setOnClickListener(v -> getdoor_Status());


        send.setOnClickListener(v ->  mHandler.sendEmptyMessageDelayed(1, 0));
        receive.setOnClickListener(v -> executorService.execute(this::receive));
        sendheart.setOnClickListener(v ->  mHandler.sendEmptyMessageDelayed(2, 0));
        sedreset.setOnClickListener(v -> sendReset());
        sendopen.setOnClickListener(v -> open(3,3));

        settem.setOnClickListener(v -> sendTem());
        getRealTem.setOnClickListener(v -> getRealTem());
        clean_times.setOnClickListener(v -> cleanTestTimes());
        battery_off.setOnClickListener(v -> batteryoff());
        TimeSyn.setOnClickListener(v -> sendTimeSyn());
        getdoor_doorStatus.setOnClickListener(v -> getdoor_lockStatus());
        device_sn.setOnClickListener(v ->getdoor_Status());

        reboottest.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    reboottest();
                }else{
                    isfirst=true;
                    isrtsp=false;
                    isRetootTest=false;
                    mHandler.removeMessages(3);
                    mHandler.removeMessages(4);
                    time=0;
                    issendReset=false;
                }
            }
        });
        Mac.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    set_mac();
                }else{
get_mac();
                }
            }
        });
        set_camera.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){

                    setcameraDirection(0,"设置左柜");
                }else{
                    setcameraDirection(1,"设置右柜");

                }
            }
        });


        set_led.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    set_led(3,"LED打开");
                }else{
                    set_led(4,"LED关闭");

                }
            }
        });
        set_vout.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    set_led(5,"vout打开");
                }else{
                    set_led(6,"vout关闭");

                }
            }
        });
        Start_stop_flow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    Log.d(TAG, "onCheckedChanged11: ");
                    succeed_Start_stop_flow=0;
                    failure_Start_stop_flow=0;
                    mHandler.sendEmptyMessageDelayed(7, 0);
                }else{
                    mHandler.removeMessages(7);
                    mHandler.removeMessages(8);

                }
            }
        });
        set_compressor.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    set_led(7,"压缩机打开");
                }else{
                    set_led(8,"压缩机关闭");

                }
            }
        });
        switch_lock.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    mHandler.sendEmptyMessageDelayed(6, 0);
                }else{
                    open_lock=0;
                    close_lock=0;
                    mHandler.removeMessages(6);
                }
            }
        });
        ipc.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    initVLC();
                    rtsp_ipc.setVisibility(View.VISIBLE);
                    mVideoSurface.requestFocus();
                    mVideoSurface.start();
                    mVideoSurface1.requestFocus();
                    mVideoSurface1.start();  // 开始播放
                }else{
                    rtsp_ipc.setVisibility(View.GONE);
                    mVideoSurface.stopPlayback();
                    mVideoSurface1.stopPlayback();
                }
            }
        });
        // 初始化线程池
        executorService = Executors.newFixedThreadPool(6);

        executorService.execute(this::receive);
        executorService.execute(this::receive1);
        executorService.execute(this::receive2);
        executorService.execute(this::receive3);
        executorService.execute(this::receive4);
        weight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                    if (socket2!=null){
                        socket2.close();
                        socket2=null;
                    }

            }
        });

    }
    private void Record(){
        startActivity(new Intent(this,MainActivity2.class));
    }
    private  void cleanTestTimes(){
        time=0;
        succeed=0;
        failure=0;
        editor.putInt("failure", 0);
        editor.putInt("succeed", 0);
        editor.apply();
        editor.commit();
        setTest_result();}

private  void sendpack(){
    DatagramSocket socket = null;
    try {
        socket = new DatagramSocket();
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }
    //创建要发送包的信息
    try{
        String str ="wlwhjc22102";
        DatagramPacket packet =new DatagramPacket(str.getBytes(),str.getBytes().length,InetAddress.getByName("192.168.1.2"), 6000);
        //发送这个包
        Log.d(TAG, "sendpack: ");
        socket.send(packet);
    } catch(Exception e){}
    //关闭socket
    finally{
        socket.close();
    }

}
//自动重启测试
    private void reboottest(){
        isRetootTest=true;
        isrtsp=false;
        addLog("重启测试结果:成功"+sp.getInt("succeed",0)+"次,"+"失败"+sp.getInt("failure",0)+"次");
        //15s内握手
        mHandler.sendEmptyMessageDelayed(3, 0);

    }
    boolean isRetootTest=false;
    boolean issendReset=false;
    boolean isrtsp=false;
    //拉流测试
    private static final String RTSP_URL = "rtsp://192.168.1.169/user=admin_password=tlJwpbo6_channel=1_stream=0&amp;onvif=0.sdp?real_st";
    private static final int TIMEOUT_MS = 15000; // 10秒超时

    private MediaPlayer mediaPlayer;
    private final Handler timeoutHandler = new Handler();
    private boolean isStreamPrepared = false;
    private void rtsptest(String s){
        mediaPlayer = new MediaPlayer();

        try {
            // 设置监听器
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.setOnErrorListener( this);
            mediaPlayer.setOnInfoListener(this);

            // 设置数据源
            mediaPlayer.setDataSource(s);

            // 开始异步准备
            mediaPlayer.prepareAsync();
            Log.d(TAG, "开始准备RTSP流...");

            // 设置超时检测
            timeoutHandler.postDelayed(timeoutRunnable, TIMEOUT_MS);
        } catch (Exception e) {
            Log.e(TAG, "设置数据源失败", e);
            handleError();
        }
    }
    // 超时检测
    private final Runnable timeoutRunnable = new Runnable() {
        @Override
        public void run() {
            if (!isStreamPrepared) {
                rtsp=false;
                isRetootTest=false;
                issendReset=false;
//    mHandler.removeMessages(3);
                time=0;
                failure++;
                editor.putInt("failure", failure);
                editor.apply();
                editor.commit();
                setTest_result();
                //重启测试失败，重新测试
                reboottest();
                Log.e(TAG, "RTSP流连接超时");
                handleError();
            }
        }
    };

    // 错误处理
    private void handleError() {
        timeoutHandler.removeCallbacks(timeoutRunnable);

        if (mediaPlayer != null) {
            try {
                mediaPlayer.release();
            } catch (Exception e) {
                Log.e(TAG, "释放MediaPlayer失败", e);
            }
            mediaPlayer = null;
        }

        // 这里可以更新UI，显示错误提示
        runOnUiThread(() -> {
            // 示例：显示错误提示
        });
    }
    DatagramSocket socket1 = null;
    DatagramSocket socket2 = null;
    DatagramSocket socket3 = null;
    DatagramSocket socket4 = null;
    DatagramSocket socket5 = null;
private void receive(){
    //接收端
    //创建socket

    UdpHandshakeParser.HandshakePacket handshake;
    try {
        socket1 = new DatagramSocket(6000);
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }

    try{
        while (true) {

            try {
                Log.d(TAG, "receive: ");
                // 接收数据
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket1.receive(packet);

//                // 处理接收到的数据
                byte[] receivedData = Arrays.copyOf(packet.getData(), packet.getLength());
                try {
                    handshake = UdpHandshakeParser.parse(receivedData);
                } catch (UdpHandshakeParser.InvalidPacketException e) {
                    throw new RuntimeException(e);
                }
                addLog("收到数据,停止发送握手请求————正在解析");


                if (handshake.Validation){
                    //15内收到握手包，发送复位包

                    if (isRetootTest){
                        if (isrtsp){
                            mHandler.removeMessages(3);
                            addLog("开始测拉流");
                            rtsptest("rtsp://192.168.1.169/user=admin_password=tlJwpbo6_channel=1_stream=0&amp;onvif=0.sdp?real_st");

                        }else{
                            mHandler.removeMessages(3);
                            Log.d(TAG, "15内收到握手包，发送复位包");
                            issendReset=true;
                            sendReset();
                            //等待4s，判断是否收到心跳包
                            mHandler.sendEmptyMessageDelayed(4, 4000);
                        }

                    }else{
                        mHandler.removeMessages(1);
                    }

                    general_port = handshake.generalPort;
                    lock_port = handshake.lockPort;
                    weight_port = handshake.weightPort;
                    temp_ctl_port = handshake.tempControlPort;

                    addLog("控制端通用端口："+handshake.generalPort);
                    addLog("控制端重力端口："+handshake.weightPort);
                    addLog("控制端门锁端口："+handshake.lockPort);
                    addLog("控制端温控端口："+handshake.tempControlPort);

                }else{
                    addLog("解析失败");
                }

            } catch (IOException e) {
                addLog("数据监听启动失败: " +e);
            }
        }
    } catch(Exception e1){


    }
    finally{
        if (socket1!=null){
            socket1.close();
            socket1=null;
        }
    }

}
private void receive1(){
    //接收端
    //创建socket
    UdpHandshakeParser.HandshakePacket handshake;
    try {
        socket2 = new DatagramSocket(6001);
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }

    try{
        while (true) {

            try {
                Log.d(TAG, "receive: ");
                // 接收数据
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket2.receive(packet);

//                // 处理接收到的数据
                byte[] receivedData = Arrays.copyOf(packet.getData(), packet.getLength());
                try {
                    handshake = UdpHandshakeParser.parse(receivedData);
                } catch (UdpHandshakeParser.InvalidPacketException e) {
                    throw new RuntimeException(e);
                }
//                addLog("收到数据,停止发送握手请求————正在解析1");
if (handshake.cmdid==769){
    addLog("收到重力数据--左传感器重力数据: "+handshake.weight_left+"--右传感器重力数据： "+handshake.weight_right+"--timestamp: "+handshake.timestamp);
}



            } catch (IOException e) {
                addLog("重力数据数据监听启动失败1: " +e);
            }
        }
    } catch(Exception e1){
        addLog("重力数据数据监听启动失败: " +e1);
        Log.d(TAG, "rece111ive1: "+e1);
    }
    finally{
        if (socket2!=null){
            socket2.close();
            socket2=null;
        }

    }

}
int lock_status=0;
int door_status=0;
private void receive2(){
    //接收端
    //创建socket
    UdpHandshakeParser.HandshakePacket handshake;
    try {
        socket3 = new DatagramSocket(6002);
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }

    try{
        while (true) {

            try {
                Log.d(TAG, "receive: ");
                // 接收数据
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket3.receive(packet);

//                // 处理接收到的数据
                byte[] receivedData = Arrays.copyOf(packet.getData(), packet.getLength());
                try {
                    handshake = UdpHandshakeParser.parse(receivedData);
                } catch (UdpHandshakeParser.InvalidPacketException e) {
                    throw new RuntimeException(e);
                }

                if (handshake.cmdid==1025)
                addLog("收到开锁回复");
                if (handshake.cmdid==1027){
                    lock_status=handshake.lock_status;
                    door_status=handshake.door_status;
                    mHandler.sendEmptyMessageDelayed(5, 0);
                    addLog("收到门锁状态上报--"+" 锁状态： "+(handshake.lock_status==0?"锁落":"锁开")+"-- 门状态: "+(handshake.door_status==0?"门关":"门开")+"-- 门锁异常码： "+(handshake.exception_code==0?"无故障":"柜顶按键按下上报"));
                }
                if (handshake.cmdid==1026){

                    lock_status=handshake.lock_status;
                    door_status=handshake.door_status;
                    mHandler.sendEmptyMessageDelayed(5, 0);
                    addLog("收到门锁状态查询回复--"+" 锁状态： "+(handshake.lock_status==0?"锁落":"锁开")+"-- 门状态: "+(handshake.door_status==0?"门关":"门开")+"-- 门锁异常码： "+(handshake.exception_code==0?"无故障":"柜顶按键按下上报"));
                }



            } catch (IOException e) {
                addLog("数据监听启动失败1: " +e);
            }
        }
    } catch(Exception e1){
        Log.d(TAG, "receive21: "+e1);
    }
    finally{
        Log.d(TAG, "receive2: ");
        if (socket3!=null){
            socket3.close();
            socket3=null;
        }

    }

}
private void receive3(){
    //接收端
    //创建socket
    UdpHandshakeParser.HandshakePacket handshake;
    try {
        socket4 = new DatagramSocket(6003);
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }

    try{
        while (true) {

            try {
                Log.d(TAG, "receive: ");
                // 接收数据
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket4.receive(packet);

//                // 处理接收到的数据
                byte[] receivedData = Arrays.copyOf(packet.getData(), packet.getLength());
                try {
                    handshake = UdpHandshakeParser.parse(receivedData);
                } catch (UdpHandshakeParser.InvalidPacketException e) {
                    throw new RuntimeException(e);
                }
                if (handshake.cmdid==1281){
                    addLog("收到 目标温度设置回复————正在解析");
                }else if (handshake.cmdid==1283){
                    addLog("收到 实时温度读取返回————正在解析");
                    addLog("实时温度: "+handshake.temp_now);
                }




            } catch (IOException e) {
                addLog("数据监听启动失败3: " +e);
            }
        }
    } catch(Exception e1){}
    finally{
        if (socket4!=null){
            socket4.close();
            socket4=null;
        }

    }

}
private void receive4(){
    //接收端
    //创建socket
    UdpHandshakeParser.HandshakePacket handshake;
    try {
        socket5 = new DatagramSocket(6004);
    } catch (SocketException e) {
        throw new RuntimeException(e);
    }

    try{
        while (true) {

            try {
                // 接收数据
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket5.receive(packet);

//                // 处理接收到的数据
                byte[] receivedData = Arrays.copyOf(packet.getData(), packet.getLength());
                try {
                    handshake = UdpHandshakeParser.parse(receivedData);
                } catch (UdpHandshakeParser.InvalidPacketException e) {
                    throw new RuntimeException(e);
                }
                Log.d(TAG, "receive: "+handshake.cmdid);

                if (handshake.cmdid==1793){
                    addLog("收到供电状态:"+handshake.status);
                    addLog("备用电池关闭下发");
                    batteryoff();
                }else if (handshake.cmdid==513){
                    addLog("收到心跳包");
                    if (issendReset){
                        isRetootTest=false;
                        issendReset=false;
                        time=0;
                        failure++;
                        editor.putInt("failure", failure);
                        editor.apply();
                        editor.commit();
                        setTest_result();
                        //重启测试失败，重新测试
                        reboottest();
                    }
                }else if (handshake.cmdid==514){
                    addLog("收到对时回复");
                }else if (handshake.cmdid==58881){
                    addLog("收到设置io口回复");
                }else if (handshake.cmdid==58885){
                    addLog("收到门状态回复： "+handshake.door_det+"---收到sn号： "+handshake.deviceSN);
                }else if (handshake.cmdid==58886){
                    addLog("收到设置柜方向回复 ");
                }else if (handshake.cmdid==58882){
                    addLog("收到设置sn号回复");
                }else if (handshake.cmdid==58887){
                    addLog("收到设置mac号回复,设置MAC"+(handshake.mac_result==1?"成功":"失败"));
                }
else if (handshake.cmdid==58888){
                    addLog("获取mac: "+handshake.mac);
                }



            } catch (IOException e) {
                addLog("数据监听启动失败: " +e);
            }
        }
    } catch(Exception e1){}
    finally{
        if (socket5!=null){
            socket5.close();
            socket5=null;
        }

    }

}
    private void startCommunication() {
        String ip = ipAddressEditText.getText().toString().trim();
        if (ip.isEmpty()) {
            showToast("请输入上位机IP地址");
            return;
        }

        try {
            appAddress = InetAddress.getByName(ip);
            isRunning = true;

            // 启动握手监听
            executorService.execute(this::startHandshakeListener);

            // 更新UI状态
            updateStatus("正在启动...");
            startButton.setEnabled(false);
            stopButton.setEnabled(true);
            sendButton.setEnabled(false);

            addLog("控制端启动，IP: 192.168.1.100");
            addLog("监听握手端口: " + HANDSHAKE_PORT);

        } catch (UnknownHostException e) {
            showToast("无效的IP地址: " + e.getMessage());
            stopCommunication();
        }
    }

    private void stopCommunication() {
        isRunning = false;

        // 关闭Socket
        if (handshakeSocket != null) {
            handshakeSocket.close();
            handshakeSocket = null;
        }

        if (dataSocket != null) {
            dataSocket.close();
            dataSocket = null;
        }

        // 更新UI状态
        runOnUiThread(() -> {
            updateStatus("已停止");
            startButton.setEnabled(true);
            stopButton.setEnabled(false);
            sendButton.setEnabled(false);
        });


        addLog("通信已停止");
    }

    private void startHandshakeListener() {
        try {
            // 绑定握手端口
            handshakeSocket = new DatagramSocket(7000,
                    InetAddress.getByName("192.168.1.2"));
            handshakeSocket.setSoTimeout(6000);

            addLog("握手监听已启动，等待上位机请求...");
            updateStatus("等待握手请求");

            while (isRunning) {
                Log.d(TAG, "startHandshakeListener: ");
                try {
                    // 接收握手请求
                    byte[] buffer = new byte[256];
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    handshakeSocket.receive(packet);

                    // 解析握手请求
                    if (isValidHandshakeRequest(packet.getData())) {
                        addLog("收到有效的握手请求");

                        // 解析上位机配置
                        parseAppConfiguration(packet.getData());

                        // 发送握手响应
                        sendHandshakeResponse();

                        // 启动数据通信
                        startDataCommunication();
                        break;
                    }
                } catch (IOException e) {
                    // 超时或其他错误，继续等待
                }
            }
        } catch (SocketException | UnknownHostException e) {
            addLog("握手监听启动失败: " + e.getMessage());
            stopCommunication();
        }
    }

    private boolean isValidHandshakeRequest(byte[] data) {
        if (data.length < 6) {
            addLog("无效请求: 数据长度不足");
            return false;
        }

        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);

        // 检查协议头
        short header = buffer.getShort();
        if (header != HEADER) {
            addLog("无效请求: 协议头错误 (0x" + Integer.toHexString(header) + ")");
            return false;
        }

        // 检查命令类型
        byte command = buffer.get();
        if (command != HANDSHAKE_REQUEST) {
            addLog("无效请求: 命令类型错误 (0x" + Integer.toHexString(command) + ")");
            return false;
        }

        // 检查数据长度
        byte dataLength = buffer.get();
        if (dataLength != 4) { // 端口配置信息应为4字节
            addLog("无效请求: 数据长度错误 (" + dataLength + ")");
            return false;
        }

        return true;
    }

    private void parseAppConfiguration(byte[] data) {
        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);

        // 跳过协议头、命令类型和数据长度字段
        buffer.position(4);

        // 读取上位机数据端口
        appDataPort = buffer.getShort() & 0xFFFF;

        addLog("解析上位机配置:");
        addLog("  上位机数据端口: " + appDataPort);
    }
    // 通信常量
    private static final String CONTROL_BOARD_IP = "192.168.1.2";

    // 协议常量
    private static final byte HEAD_LOW = (byte) 0x55;
    private static final byte HEAD_HIGH = (byte) 0xAA;
    private static final byte CMD_ID_LOW = 0x01;
    private static final byte CMD_ID_HIGH = 0x01;
    private static final byte CMD_TYPE_HANDSHAKE = 0x01;
    private static final int HANDSHAKE_PACKET_SIZE = 46;

    // 运行状态

    // 线程池
    private final ExecutorService executor = Executors.newFixedThreadPool(4);
    private final Handler mainHandler = new Handler(Looper.getMainLooper());
        // 全局计数器（持久化存储）
        private int globalCounter = 0;
        private static final String PREFS_NAME = "UDPPrefs";
        private static final String GLOBAL_CNT_KEY = "global_counter";
    private void initGlobalCounter(Context context) {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        globalCounter = prefs.getInt(GLOBAL_CNT_KEY, 1); // 默认从1开始
    }
        private void saveGlobalCounter(Context context) {
            SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
            prefs.edit().putInt(GLOBAL_CNT_KEY, globalCounter).apply();
        }

        // 获取并递增全局计数器
        private int getAndIncrementGlobalCounter() {
            initGlobalCounter(this);
            int current = globalCounter++;

            // 处理16位溢出 (0-65535)
            if (globalCounter > 0xFFFF) {
                globalCounter = 1; // 循环计数
            }
            saveGlobalCounter(this);
            return current;
        }

  //发送握手请求
    private void sendHandshakeResponse() {

        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建46字节的响应包
            byte[] response = new byte[HANDSHAKE_PACKET_SIZE];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = CMD_ID_LOW;
            response[index++] = CMD_ID_HIGH;

            // 命令类型 (0x02表示握手响应)
            response[index++] = CMD_TYPE_HANDSHAKE;

            // Global Count (示例值: 1)
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF); // 高字节

            // 总长度 (46字节)
            response[index++] = (byte) HANDSHAKE_PACKET_SIZE;



            // 端口配置 (偏移量)
            response[index++] = 0X01; // weight_port (7000 + 0 = 7000)
            response[index++] = 0X02; // lock_port (7000 + 1 = 7001)
            response[index++] = 0X03; // temp_ctl_port (7000 + 2 = 7002)
            response[index++] = 0X04; // general_port (7000 + 3 = 7003)
            String item_id = "20230216295";
            byte[] itemIdBytes = new byte[32];
            byte[] tempBytes = item_id.getBytes();
            System.arraycopy(tempBytes, 0, itemIdBytes, 0, tempBytes.length);
            System.arraycopy(itemIdBytes, 0, response, index, itemIdBytes.length);
            index += 32;
            Log.d(TAG, "sendHandshakeResponse2: "+response.toString());

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 44));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            // 发送握手响应
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7000
            );

            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();

addLog("握手请求已发送，等待控制板应答");
            Log.i("UDP", "握手请求已发送");

        } catch (IOException e) {
            addLog("发送握手请求失败: " + e.getMessage());
            Log.e("UDP", "发送握手请求失败: " + e.getMessage());
        }
    }
    //发送心跳请求
    int general_port=6000;
    int lock_port=6000;
    int weight_port=6000;
    int temp_ctl_port=6000;
    private void sendHeartBeatResponse() {
        try {
        DatagramSocket socket =new DatagramSocket();
        // 创建46字节的响应包
        byte[] response = new byte[10];
        int index = 0;

        // 包头
        response[index++] = HEAD_LOW;
        response[index++] = HEAD_HIGH;

        // 命令ID
        response[index++] = CMD_ID_LOW;
        response[index++] = 0x02;

        // 命令类型 ()
        response[index++] = CMD_TYPE_HANDSHAKE;
        int globalCnt = getAndIncrementGlobalCounter();
        response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
        response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
        response[index++] = (byte) 10;
//crc
        int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));
        response[index++] = (byte) (crc & 0xFF);        // CRC低字节
        response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
        // 发送心跳包
        DatagramPacket packet = new DatagramPacket(
                response,
                response.length,
                InetAddress.getByName("192.168.1.2"),
                7004
        );
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        addLog("心跳请求已发送，等待控制板应答");
    } catch (IOException e) {
        addLog("发送心跳请求失败: " + e.getMessage());
        Log.e("UDP", "发送心跳请求失败: " + e.getMessage());
    }
    }
    //复位下发
    private void sendReset() {
        try {
        DatagramSocket socket =new DatagramSocket();
        // 创建46字节的响应包
        byte[] response = new byte[11];
        int index = 0;

        // 包头
        response[index++] = HEAD_LOW;
        response[index++] = HEAD_HIGH;

        // 命令ID
        response[index++] = 0x03;
        response[index++] = 0x02;

        // 命令类型 ()
        response[index++] = (byte)0;
        int globalCnt = getAndIncrementGlobalCounter();
        response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
        response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
        response[index++] = (byte) 11;

           // 复位mcu
        response[index++] = (byte)0x00 ;
//crc
        int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 9));
        response[index++] = (byte) (crc & 0xFF);        // CRC低字节
        response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
        // 发送复位
        DatagramPacket packet = new DatagramPacket(
                response,
                response.length,
                InetAddress.getByName("192.168.1.2"),
                7004
        );
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        addLog("复位包已发送");
    } catch (IOException e) {
        addLog("发送复位包失败: " + e.getMessage());
        Log.e("UDP", "发送复位包失败: " + e.getMessage());
    }
    }
    //对时下发
    private void sendTimeSyn() {
        try {
        DatagramSocket socket =new DatagramSocket();
        // 创建46字节的响应包
        byte[] response = new byte[18];
        int index = 0;

        // 包头
        response[index++] = HEAD_LOW;
        response[index++] = HEAD_HIGH;

        // 命令ID
        response[index++] = 0x02;
        response[index++] = 0x02;

        // 命令类型 ()
        response[index++] = 0x01;
        int globalCnt = getAndIncrementGlobalCounter();
        response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
        response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
        response[index++] = (byte) 18;
        //时间戳
            long timestamp = System.currentTimeMillis();
            for (int i = 0; i < 8; i++) {
                response[index++]  =  (byte) (timestamp & 0xFF); // 8-15: timestamp (LSB first)
                timestamp >>= 8;
            }

        int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 16));
        response[index++] = (byte) (crc & 0xFF);        // CRC低字节
        response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
        // 发送复位
        DatagramPacket packet = new DatagramPacket(
                response,
                response.length,
                InetAddress.getByName("192.168.1.2"),
                7004
        );
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        addLog("复位包已发送");
    } catch (IOException e) {
        addLog("发送复位包失败: " + e.getMessage());
        Log.e("UDP", "发送复位包失败: " + e.getMessage());
    }
    }
    //设置目标温度下发
    private void sendTem() {
        if (String.valueOf(tem.getText()).equals("")){
            addLog("目标温度不能为空");
        }else{try {
            DatagramSocket socket =new DatagramSocket();
            // 创建46字节的响应包
            byte[] response = new byte[11];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x01;
            response[index++] = 0x05;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            //total_length
            response[index++] = (byte) 11;
            //目标温度，单位为度
            response[index++] = (byte) Byte.valueOf(String.valueOf(tem.getText()));
            //crc
            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 9));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            // 发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7003
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog(" 目标温度设置下发");
        } catch (IOException e) {
            addLog("目标温度设置下发失败: " + e.getMessage());
            Log.e("UDP", "目标温度设置下发失败: " + e.getMessage());
        }}

    }
    //实时温度读取下发
    private void getRealTem() {
        try {
        DatagramSocket socket =new DatagramSocket();
        // 创建46字节的响应包
        byte[] response = new byte[10];
        int index = 0;

        // 包头
        response[index++] = HEAD_LOW;
        response[index++] = HEAD_HIGH;

        // 命令ID
        response[index++] = 0x03;
        response[index++] = 0x05;

        // 命令类型 ()
        response[index++] = 0x01;
        int globalCnt = getAndIncrementGlobalCounter();
        response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
        response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
        //total_length
        response[index++] = (byte) 10;
        //crc
        int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));
        response[index++] = (byte) (crc & 0xFF);        // CRC低字节
        response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
        // 发送
        DatagramPacket packet = new DatagramPacket(
                response,
                response.length,
                InetAddress.getByName("192.168.1.2"),
                7003
        );
        new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    socket.send(packet);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        addLog(" 实时温度读取下发");
    } catch (IOException e) {
        addLog("实时温度读取下发失败: " + e.getMessage());
        Log.e("UDP", "实时温度读取下发失败: " + e.getMessage());
    }
    }

    //开锁下发
    private  void open(int open_lock_timeout,int open_door_timeout){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建46字节的响应包
            byte[] response = new byte[13];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x01;
            response[index++] = 0x04;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 13;

            //lock_opt
            response[index++] = (byte) 1;
            //open_lock_timeout
            response[index++] = (byte) open_lock_timeout;
            //open_door_timeout
            response[index++] = (byte) open_door_timeout;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 11));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送开锁
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7002
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("开锁包已发送");
        } catch (IOException e) {
            addLog("发送开锁包失败: " + e.getMessage());
            Log.e("UDP", "发送开锁包失败: " + e.getMessage());
        }

    }

    //门锁状态查询下发
    private  void getdoor_lockStatus(){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建10字节的响应包
            byte[] response = new byte[10];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x02;
            response[index++] = 0x04;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 10;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));

            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7002
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("门锁状态查询下发");
        } catch (IOException e) {
            addLog("门锁状态查询下发失败: " + e.getMessage());
            Log.e("UDP", "门锁状态查询下发失败: " + e.getMessage());
        }

    }
    //门锁状态查询下发
    private  void getdeviceStatus(){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建10字节的响应包
            byte[] response = new byte[10];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x05;
            response[index++] = (byte) 0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 10;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));

            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("门锁状态查询下发");
        } catch (IOException e) {
            addLog("门锁状态查询下发失败: " + e.getMessage());
            Log.e("UDP", "门锁状态查询下发失败: " + e.getMessage());
        }

    }
    // 备用电池关闭下发
    private  void batteryoff(){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建46字节的响应包
            byte[] response = new byte[10];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x02;
            response[index++] = 0x07;

            // 命令类型 ()
            response[index++] = 0x00;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 10;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("备用电池关闭下发");
        } catch (IOException e) {
            addLog("备用电池关闭下发失败: " + e.getMessage());
            Log.e("UDP", "备用电池关闭下发失败: " + e.getMessage());
        }

    }
    // 设置io口下发
    private  void set_led(int i,String s){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建46字节的响应包
            byte[] response = new byte[11];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x01;
            response[index++] = (byte) 0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 11;
            //开（3）或关（4）
            response[index++] = (byte) i;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 9));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog(s+"下发");
        } catch (IOException e) {
            addLog(s+"下发失败: " + e.getMessage());
            Log.e("UDP", s+"下发失败: " + e.getMessage());
        }

    }

    // 设置camera方向
    private  void setcameraDirection(int i,String s){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建响应包
            byte[] response = new byte[11];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x06;
            response[index++] = (byte) 0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 11;
            //开（3）或关（4）
            response[index++] = (byte) i;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 9));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog(s+"下发");
        } catch (IOException e) {
            addLog(s+"下发失败: " + e.getMessage());
            Log.e("UDP", s+"下发失败: " + e.getMessage());
        }

    }

    // 设置camera方向

    //对时下发
    private void setSn() {
        if (String.valueOf(tem.getText()).equals("")){
            addLog("sn号不能为空");
            return;
        }
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建42字节的响应包
            byte[] response = new byte[42];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x02;
            response[index++] = (byte)0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 42;
            //SN号
            String  sn = String.valueOf(tem.getText());
            byte[] inputBytes = sn.getBytes(StandardCharsets.UTF_8);
            for (int i = 0; i < inputBytes.length; i++) {
                Log.d(TAG, "setSn233: "+inputBytes[i]);
            }
            int bytesToCopy = Math.min(inputBytes.length, 32);
            Log.d(TAG, "setSn--sn号实际字节数： "+bytesToCopy);
            if (bytesToCopy>32){
                addLog("sn号字节数超过32，设置失败");
                return;
            }
            System.arraycopy(inputBytes, 0, response, 8, bytesToCopy);
            index+=bytesToCopy;
            for (int i = 1; i <=32-bytesToCopy; i++) {
                response[index++] = 0;
            }
//            for (int i = 0; i < 8; i++) {
//                response[index++]  =  (byte) (timestamp & 0xFF); // 8-15: timestamp (LSB first)
//                timestamp >>= 8;
//            }

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 40));
            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            Log.d(TAG, "setSn11: "+response);


            // 发送复位
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("SN号已发送");
        } catch (IOException e) {
            addLog("发送SN号失败: " + e.getMessage());
            Log.e("UDP", "发送SN号失败: " + e.getMessage());
        }
    }

    //门状态查询下发
    private  void getdoor_Status(){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建10字节的响应包
            byte[] response = new byte[10];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x05;
            response[index++] = (byte) 0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 10;

            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));

            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("门状态查询下发");
        } catch (IOException e) {
            addLog("门状态查询下发失败: " + e.getMessage());
            Log.e("UDP", "门状态查询下发失败: " + e.getMessage());
        }

    }

    //设置MAC地址
    private  void set_mac(){
        if (String.valueOf(tem.getText()).equals("")){
            addLog("MAC不能为空");
            return;
        }
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建28字节的响应包
            byte[] response = new byte[28];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x07;
            response[index++] = (byte) 0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 28;
//mac

            String  mac = String.valueOf(tem.getText());
            byte[] inputBytes = mac.getBytes(StandardCharsets.UTF_8);
            for (int i = 0; i < inputBytes.length; i++) {
                Log.d(TAG, "setSn233: "+inputBytes[i]);
            }
            int bytesToCopy = Math.min(inputBytes.length, 18);
            Log.d(TAG, "setSn--sn号实际字节数： "+bytesToCopy);
            if (bytesToCopy>18){
                addLog("sn号字节数超过32，设置失败");
                return;
            }
            System.arraycopy(inputBytes, 0, response, 8, bytesToCopy);
            index+=bytesToCopy;
            for (int i = 1; i <=18-bytesToCopy; i++) {
                response[index++] = 0;
            }
            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 26));

            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("设置MAC地址下发");
        } catch (IOException e) {
            addLog("设置MAC地址下发失败: " + e.getMessage());
            Log.e("UDP", "设置MAC地址下发失败: " + e.getMessage());
        }

    }

    //获取MAC地址
    private  void get_mac(){
        try {
            DatagramSocket socket =new DatagramSocket();
            // 创建28字节的响应包
            byte[] response = new byte[10];
            int index = 0;

            // 包头
            response[index++] = HEAD_LOW;
            response[index++] = HEAD_HIGH;

            // 命令ID
            response[index++] = 0x08;
            response[index++] = (byte) 0xe6;

            // 命令类型 ()
            response[index++] = 0x01;
            int globalCnt = getAndIncrementGlobalCounter();
            response[index++] = (byte) (globalCnt & 0xFF);        // 低字节
            response[index++] = (byte) ((globalCnt >> 8) & 0xFF);
            response[index++] = (byte) 10;
            int crc =Crc16Utils.calcCrc16(Arrays.copyOfRange(response, 0, 8));

            response[index++] = (byte) (crc & 0xFF);        // CRC低字节
            response[index] = (byte) ((crc >> 8) & 0xFF);   // CRC高字节
            //发送
            DatagramPacket packet = new DatagramPacket(
                    response,
                    response.length,
                    InetAddress.getByName("192.168.1.2"),
                    7004
            );
            new Thread(new Runnable(){
                @Override
                public void run() {
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }).start();
            addLog("获取MAC地址");
        } catch (IOException e) {
            addLog("获取MAC地址: " + e.getMessage());
            Log.e("UDP", "获取MAC地址失败: " + e.getMessage());
        }

    }
int time=0;
int succeed=0;
int failure=0;
    SharedPreferences sp;
    SharedPreferences.Editor editor;
//开关锁次数
    int open_lock=0;
    int close_lock=0;
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch(msg.what){
                case 1:
                    //10s周期性发送握手请求
                    sendHandshakeResponse();

            break;
                case 2:
                sendHeartBeatResponse();
                mHandler.sendEmptyMessageDelayed(2, 2000);
                    break;
                case 3:

                    time++;
                    sendHandshakeResponse();
                    if (time==15){
                        isRetootTest=false;
                        mHandler.removeMessages(3);
                        time=0;
                        failure++;
                        editor.putInt("failure", failure);
                        editor.apply();
                        editor.commit();
                        setTest_result();
                        //重启测试失败，重新测试
                        reboottest();
                    }else
                    mHandler.sendEmptyMessageDelayed(3, 3000);
                    break;
                case 4:
if (issendReset){
    issendReset=false;
    isrtsp = true;
    time=0;
    mHandler.sendEmptyMessageDelayed(3, 1000);

}
                    break;
                case 5:
lockstatusTextView.setText("锁状态： "+(lock_status==0?"锁落":"锁开"));
doorstatusTextView.setText("门状态： "+(door_status==0?"门关":"门开"));
                    break;
                    //测锁
                case 6:
                    open_lock++;
                    close_lock++;
                    switch_lock_result.setText("开锁： "+open_lock+"次----"+"关锁： "+close_lock+"次");
open(2,0);
                    mHandler.sendEmptyMessageDelayed(6, 3000);
                    break;

                    //启停流测试
                case 7:
                    Start_stop_flow_result.setText("启停流测试成功: "+succeed_Start_stop_flow+"  启停流测试失败:  "+failure_Start_stop_flow);
initVLC();
                    rtsp_ipc.setVisibility(View.VISIBLE);
                    mVideoSurface.requestFocus();
                    mVideoSurface.start();
                    mVideoSurface1.requestFocus();
                    mVideoSurface1.start();
                    Log.d(TAG, "handleMessage222: ");
                    mHandler.sendEmptyMessageDelayed(8, 15000);
break;
                case 8:
                    Log.d(TAG, "handleMessage11111: ");
                    rtsp_ipc.setVisibility(View.GONE);
                    mVideoSurface.stopPlayback();
                    mVideoSurface1.stopPlayback();
                    mHandler.sendEmptyMessageDelayed(7, 15000);
break;
            }
        }
    };

    private int calculateCRC(byte[] data) {
        // 简化的CRC16计算 (实际应根据协议要求实现)
        int crc = 0xFFFF;
        for (byte b : data) {
            crc = (crc << 8) ^ b;
        }
        return crc & 0xFFFF;
    }

    private  void setTest_result(){
        int succeed = sp.getInt("succeed",-1);
        int failure = sp.getInt("failure",-1);
        test_result.setText("成功： "+succeed+"次"+"-----失败： "+failure+"次");
    }

    private byte[] createHandshakeResponse() {
        // 计算数据部分长度
        int dataLength = 1 + 2 + DEVICE_ID.length() + SERIAL_NUMBER.length() + 2;

        // 创建缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(4 + dataLength)
                .order(ByteOrder.BIG_ENDIAN);

        // 协议头
        buffer.putShort(HEADER);

        // 命令类型
        buffer.put(HANDSHAKE_RESPONSE);

        // 数据长度
        buffer.put((byte) dataLength);

        // 协议版本
        buffer.put(PROTOCOL_VERSION);

        // 软件版本
        buffer.putShort(SOFTWARE_VERSION);

        // 设备标识
        buffer.put(DEVICE_ID.getBytes());

        // SN号
        buffer.put(SERIAL_NUMBER.getBytes());

        // 控制端数据端口
        buffer.putShort((short) DATA_PORT);

        return buffer.array();
    }

    private void startDataCommunication() {
        handler.post(() -> {
            updateStatus("数据通信中");
            sendButton.setEnabled(true);
        });

        addLog("\n开始数据通信...");
        addLog("控制端数据端口: " + DATA_PORT);
        addLog("上位机数据端口: " + appDataPort);

        // 启动数据监听
        executorService.execute(this::startDataListener);
    }

    private void startDataListener() {
        try {
            // 绑定到192.168.1.2的数据端口
            dataSocket = new DatagramSocket(6000,
                    InetAddress.getByName("192.168.1.2"));
            dataSocket.setSoTimeout(1000);

            addLog("数据监听已启动");
            UdpHandshakeParser.HandshakePacket handshake;
            while (isRunning) {
                try {
                    // 接收数据
                    byte[] buffer = new byte[1024];
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    dataSocket.receive(packet);

                    // 处理接收到的数据
                    byte[] receivedData = Arrays.copyOf(packet.getData(), packet.getLength());
//                    String message = new String(packet.getData(), 0, packet.getLength());
//                    if (receivedData.length == 46) {
                        try {
                             handshake = UdpHandshakeParser.parse(receivedData);
                        } catch (UdpHandshakeParser.InvalidPacketException e) {
                            throw new RuntimeException(e);
                        }
                    addLog("控制端通用端口："+handshake.generalPort);
                        // 处理解析结果

//                    }
                    addLog("收到数据,停止发送握手请求");
                    mHandler.removeCallbacksAndMessages(null);
                } catch (IOException e) {
                    // 超时继续监听
                }
            }
        } catch (SocketException | UnknownHostException e) {
            addLog("数据监听启动失败: " + e.getMessage());
            stopCommunication();
        }
    }

    private void sendDataMessage() {
        // 在实际应用中，这里会发送具体的数据
        // 这里发送一个示例消息
        String message = "控制端状态: 正常运行";
        sendData(message);
    }
    private  void setDeletelog(){
        logTextView.setText("");
    }

    private void sendData(String message) {
        executorService.execute(() -> {
            try {
                byte[] data = message.getBytes();
                DatagramPacket packet = new DatagramPacket(
                        data, data.length, appAddress, appDataPort);

                dataSocket.send(packet);
                addLog("发送数据: " + message);

            } catch (IOException e) {
                addLog("发送数据失败: " + e.getMessage());
            }
        });
    }

    private void updateStatus(String status) {
//        handler.post(() -> statusTextView.setText("状态: " + status));
    }

    private void addLog(String log) {
        handler.post(() -> {
            String timestamp = timeFormat.format(new Date());
            String logEntry = "[" + timestamp + "] " + log + "\n";
            logTextView.append(logEntry);

            // 自动滚动到底部
            logScrollView.post(() -> logScrollView.fullScroll(View.FOCUS_DOWN));
        });
    }

    private void showToast(String message) {
        handler.post(() -> Toast.makeText(
                MainActivity.this, message, Toast.LENGTH_SHORT).show());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
        stopCommunication();
        if (mReadThread != null)
            mReadThread.interrupt();
        if (mSendThread != null)
            mSendThread.interrupt();
        if (serialPort != null) {
            serialPort.close();
            serialPort = null;
        }
        if (socket1!=null){
            socket1.close();
            socket1=null;
        }
        if (socket2!=null){
            socket2.close();
            socket2=null;
        }
        if (socket3!=null){
            socket3.close();
            socket3=null;
        }
        if (socket4!=null){
            socket4.close();
            socket4=null;
        }
        if (socket5!=null){
            socket5.close();
            socket5=null;
        }
        mHandler.removeCallbacksAndMessages(null);
        if (mMediaPlayer!=null){
//            mMediaPlayer.stop();
            mMediaPlayer.release();
        }
        if (mMediaPlayer1!=null){
//            mMediaPlayer1.stop();
            mMediaPlayer1.release();
        }


        mLibVLC.release();
        executor.shutdownNow();


        executorService.shutdown();
        timeoutHandler.removeCallbacks(timeoutRunnable);
        if (mediaPlayer != null) {
            mediaPlayer.release();
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Log.e(TAG, "播放错误: what=" + what + ", extra=" + extra);
        rtsp=false;
        isRetootTest=false;
        issendReset=false;
        time=0;
        failure++;
        editor.putInt("failure", failure);
        editor.apply();
        editor.commit();
        setTest_result();
        //重启测试失败，重新测试
        reboottest();
        handleError();
        return true; // 表示已处理错误
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        switch (what) {
            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                Log.d(TAG, "缓冲开始...");
                break;
            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                Log.d(TAG, "缓冲结束");
                break;
            case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                Log.i(TAG, "视频开始渲染");
                break;
        }
        return false;
    }
boolean rtsp=false;
boolean isfirst=true;
    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.i(TAG, "RTSP流准备完成，开始播放");
        isStreamPrepared = true;

        timeoutHandler.removeCallbacks(timeoutRunnable);
        if (isfirst){
            isfirst=false;
            rtsptest("rtsp://192.168.1.168/user=admin_password=tlJwpbo6_channel=1_stream=0&amp;onvif=0.sdp?real_st");
        }else{
            isfirst=true;
            addLog("测试成功");
            rtsp=true;
            isRetootTest=false;
            issendReset=false;
            time=0;
            succeed++;
            editor.putInt("succeed", succeed);
            editor.apply();
            editor.commit();
            //测试成功，重新测试
            setTest_result();
            reboottest();
        }
    }
}